package com.unitd.frame.comm.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @desc 资源文件加载工具类
 * @filename PropertiesUtils.java
 * @copyright www.unitd.com
 * @author Hudan
 * @version 1.0
 * @date 2016/11/13
 */
public class PropertiesUtils extends PropertiesLoaderUtils {

	private static final Logger logger = LoggerFactory.getLogger(PropertiesUtils.class);

	/** 是否已进行初始化加载 */
	private static boolean inited;
	 /** 具体应用的配置文件路径(配置文件根路径相同,根据传递的参数获取某具体的应用下的属性文件) */
	private static String appCfgDir;
	 /** 数据对象集合 */
	private static Map<String, String> propertiesMap = new HashMap<>();

	public static void initAppCfgDir(String appCfg) {
		appCfgDir = appCfg;
	}

	private synchronized static void load() {
		try {
			if (inited) {
				return;
			}

			// 获取当前应用的配置文件目录信息,默认当前类路径
			File dir = new File(Thread.currentThread().getContextClassLoader().getResource("").getPath());
			logger.info("当前运行目录:" + dir.getAbsolutePath());
			// 加载当前运行时的类路径下的properties属性文件
			loadPropertiesFromFile(dir);

			String classPath = dir.getAbsolutePath();
			// 如果当前运行时是test目录下的Junit的测试方法,则默认读取的当前类路径为test-classes,这是需要将main目录下的classes的类路径也加载进去,故增加此判断来进行处理
			if (classPath.endsWith(File.separator + "test-classes")) {
				// 获取classes目录
				String newClassPath = classPath.substring(0, classPath.lastIndexOf(File.separator + "test-classes")) + File.separator + "classes";

				// 加载classes目录下的properties属性配置文件
				dir = new File(newClassPath);
				loadPropertiesFromFile(dir);
			}
			inited = true;
		} catch (Exception e) {
			inited = true;
			throw new RuntimeException(e);
		}
	}

	/**
	 * @desc 加载指定路径下的properties属性文件,并将属性值按照key-value存入map集合
	 * @param proFilePath 属性文件路径
	 */
	private synchronized static void loadPropertiesFromFile(File proFilePath) throws IOException {
		File[] files = proFilePath.listFiles();
		if(files==null || files.length==0) {
			return;
		}

		for (File file : files) {
			if (file.isDirectory()) {
				loadPropertiesFromFile(file);
			} else {
				String path = file.getPath();
				if (path.endsWith("properties")) {
					if (path.contains("i18n")) {
						continue;
					}

					Properties p = new Properties();
					p.load(new FileReader(file));
					for (String key : p.stringPropertyNames()) {
						String value = p.getProperty(key);
						if(StringUtils.isNotEmpty(value)) {
							propertiesMap.put(key, value);
						}
					}
					System.out.println("load properties from file:" + path);
				}
			}
		}
	}

	/**
	 * @desc 根据属性key获取对应的属性值,如果不存在或改属性值为空,则赋予默认值
	 * @param key 属性key
	 * @param defaultValue 默认值
	 * @return String
	 */
	public static synchronized String get(String key, String... defaultValue) {
		if (!inited) {
			load();
		}
		if (propertiesMap.containsKey(key)) {
			return propertiesMap.get(key);
		}
		if (defaultValue != null && defaultValue.length > 0 && defaultValue[0] != null) {
			return defaultValue[0];
		} else {
			return System.getProperty(key);
		}
	}

	/**
	 * @desc 根据属性key获取对应的整型属性值,如果不存在或改属性值为空,则赋予默认值
	 * @param key 属性key
	 * @param defalutValue 默认值
	 * @return int
	 */
	public static synchronized int getInt(String key, int defalutValue) {
		String v = get(key);
		if (v != null) {
			return Integer.parseInt(v);
		}
		return defalutValue;
	}

	/**
	 * @desc 根据属性key获取对应的Long属性值,如果不存在或改属性值为空,则赋予默认值
	 * @param key 属性key
	 * @param defalutValue 默认值
	 * @return long
	 */
	public static synchronized long getLong(String key, long defalutValue) {
		String v = get(key);
		if (v != null) {
			return Long.parseLong(v);
		}
		return defalutValue;
	}

	/**
	 * @desc 获取当前应用的路径
	 * @return String
	 */
	public static String getProjectPath() {
		// 如果配置了工程路径，则直接返回，否则自动获取。
		String projectPath = get("projectPath");
		if (StringUtils.isNotBlank(projectPath)) {
			return projectPath;
		}
		try {
			File file = new DefaultResourceLoader().getResource("").getFile();
			if (file != null) {
				while (true) {
					File f = new File(file.getPath() + File.separator + "src" + File.separator + "main");
					if (f == null || f.exists()) {
						break;
					}
					if (file.getParentFile() != null) {
						file = file.getParentFile();
					} else {
						break;
					}
				}
				projectPath = file.toString();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return projectPath;
	}
}